from rest_framework.response import Response
from rest_framework import status
import logging

from utils.errors import ERROR_CODE_MAPPING


class BaseResponse:
    def __init__(self, code1="0", code2="00", code3="00", data=None, message=None):
        """
        初始化 BaseResponse 对象
        :param code1: 错误码1（通常为大类别）
        :param code2: 错误码2（模块级别错误码）
        :param code3: 错误码3（具体错误类型）
        :param data: 返回的数据
        :param message: 错误信息
        """
        # 校验错误码格式，确保长度和类型
        self.code1 = self._validate_code(code1, 1, "0")
        self.code2 = self._validate_code(code2, 2, "00")
        self.code3 = self._validate_code(code3, 2, "00")
        self.data = data
        self.message = message or self._get_default_message()

    def _validate_code(self, code, length, default):
        """
        校验错误码格式，确保长度和类型
        :param code: 错误码
        :param length: 错误码的长度
        :param default: 默认值
        :return: 校验后的错误码
        """
        return str(code).zfill(length) if isinstance(code, str) and len(code) == length else default

    @property
    def code(self):
        """
        拼接返回的完整错误码
        :return: 拼接后的完整错误码
        """
        return self.code1 + self.code2 + self.code3

    @property
    def dict(self):
        """
        将响应数据转换为字典格式
        :return: 格式化后的字典
        """
        return {
            'code': self.code,
            'data': self.data,
            'message': self.message
        }

    def _get_default_message(self):
        """
        根据错误码生成默认的data值。
        可以根据需要调整，譬如根据不同的错误码返回不同的默认data。
        """
        # 假设错误码与默认data的映射是这样的
        full_code = self.code
        return ERROR_CODE_MAPPING.get(full_code, "未知错误")



class ResponseUtil:
    """
    自定义响应工具类，简化响应返回
    """

    @staticmethod
    def success(data=None, message="成功"):
        """
        成功响应
        :param data: 返回数据
        :param message: 成功消息
        """
        return Response(BaseResponse(data=data, message=message).dict, status=status.HTTP_200_OK)

    @staticmethod
    def error(code1="1", code2="00", code3="00", data=None, message=None):
        """
        错误响应
        :param code1: 错误码1（大类别）
        :param code2: 错误码2（模块编号）
        :param code3: 错误码3（具体错误类型）
        :param message: 错误信息（若不提供，自动从映射表获取）
        :param data: 额外返回的数据
        """
        response_data = BaseResponse(
            code1=code1,
            code2=code2,
            code3=code3,
            data=data,
            message=message
        ).dict
        logging.error(f"Error Response: {response_data}")
        return Response(response_data, status=status.HTTP_200_OK)

    @staticmethod
    def warn(code2="00", message="警告信息", data=None):
        """
        警告响应
        :param code2: 模块编号
        :param message: 警告消息
        :param data: 额外数据
        """
        return ResponseUtil.error(code1="2", code2=code2, code3="00", message=message, data=data)

    @staticmethod
    def unauthorized(message="权限不足"):
        """
        未授权响应
        """
        return ResponseUtil.error(code1="1", code2="00", code3="03", message=message)

    @staticmethod
    def not_found(message="资源不存在"):
        """
        资源未找到响应
        """
        return ResponseUtil.error(code1="1", code2="00", code3="04", message=message)

    @staticmethod
    def server_error(message="服务器内部错误"):
        """
        服务器内部错误响应
        """
        return ResponseUtil.error(code1="1", code2="00", code3="08", message=message)

    @staticmethod
    def custom(code, message="自定义响应", data=None, http_status=status.HTTP_200_OK):
        """
        自定义响应
        :param code: 自定义完整错误码
        :param message: 响应消息
        :param data: 额外数据
        :param http_status: HTTP 状态码
        """
        response_data = {
            'code': code,
            'data': data or {},
            'message': message
        }
        return Response(response_data, status=http_status)
